package com.alibaba.citrus.cr.price.ability.functions.factory.activity.process;

import com.alibaba.citrus.common.Result;
import com.alibaba.citrus.cr.price.ability.functions.entity.activity.*;
import com.alibaba.citrus.cr.price.repository.ActivityQueryRepository;
import com.alibaba.citrus.cr.common.annotation.FunctionInvoker;
import com.alibaba.citrus.cr.common.annotation.ProcessInvoker;
import com.alibaba.citrus.cr.common.exception.ProcessException;
import com.alibaba.citrus.cr.price.ability.functions.factory.activity.SegmentedActivityCombinationFactory;
import com.alibaba.citrus.cr.price.ability.functions.factory.activity.SegmentedActivityTermFactory;
import com.alibaba.cz.base.tool.log.Log;
import com.epoch.app.crpricecenter.dto.request.ActivityInfoRequest;
import com.epoch.app.crpricecenter.dto.request.ActivityItemInfo;
import com.epoch.app.crpricecenter.dto.request.ActivityItemInfoRequest;
import com.epoch.app.crpricecenter.dto.request.ParticipateActivityInfoRequest;
import com.epoch.app.crpricecenter.dto.request.ParticipateActivityTermRequest;
import com.epoch.app.crpricecenter.dto.response.ActivityTermResponse;
import com.epoch.app.crpricecenter.model.dto.SegmentedActivityCombinationSDO;
import com.epoch.app.crpricecenter.model.enums.ActivityTypeEnum;
import com.epoch.app.crpricecenter.sdo.ActivityTermSDO;
import com.epoch.app.crpricecenter.sdo.ActivityTitleExtSDO;
import com.epoch.app.crpricecenter.sdo.ActivityTitleSDO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.Nullable;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: qiaojiange
 * @create: 2021/11/18
 * @Description 特价活动处理器
 */
@Component
public class SpecialPriceProcessor extends ActivityProcess {

    @Resource
    private ActivityQueryRepository queryRepository;

    private static Log log = Log.getLogger(SpecialPriceProcessor.class);

    @Override
    public List<ActivityTermEntity> addInfo(ActivityTitleEntity titleEntity,
                                            String itemId, String saleUnit) {

        Set<ActivityTermSDO> activityTermSDOS = queryRepository.queryTermSDOList(titleEntity.obtainActivityId(), saleUnit);

        List<ActivityTermEntity> result = new ArrayList<>();
        activityTermSDOS.forEach(sdo -> {
            ActivityTermEntity termEntity = ActivityTermEntity.of(sdo);

            List<String> itemIdList = queryRepository.queryTermAndItemRelationByTermId(sdo.getActivityId(), sdo.getActivityTermId());
            termEntity.setItemList(itemIdList);

//          原品 ID为空，查询坎级活动表
            List<SegmentedActivityTermEntity> segmentedActivityTermEntityList = new ArrayList<>();
            if (termEntity.containItemId(itemId)) {
                //1. 获取坎级活动列表,同时对坎级活动每一项都填充坎级组合列表
                segmentedActivityTermEntityList =
                        SegmentedActivityTermFactory.create(titleEntity.obtainActivityId(), termEntity.obtainActivityTermId());


                termEntity.setSegmentedActivityTermEntityList(segmentedActivityTermEntityList);
            }

            //   2. 坎级活动表查不到，直接查询坎级组合表,计算组合特价
            if (CollectionUtils.isEmpty(segmentedActivityTermEntityList)) {
                List<SegmentedActivityCombinationEntity> segmentedActivityCombinationEntityList =
                        SegmentedActivityCombinationFactory.createByItemId(titleEntity.obtainActivityId(), termEntity.obtainActivityTermId());
                termEntity.setCombinationEntityList(segmentedActivityCombinationEntityList);
                List<SegmentedActivityCombinationEntity> allSegmentedActivityCombinationEntityList =
                        SegmentedActivityCombinationFactory.createByItemId(titleEntity.obtainActivityId(), "");
                termEntity.setAllCombinationEntityList(allSegmentedActivityCombinationEntityList);
            }
            result.add(termEntity);
        });
        return result;
    }

    @Override
    public String getActivityTypeDesc() {
        return ActivityTypeEnum.SPECIAL_OFFER_PRICE.getValue();
    }

    @Override
    public List<ActivityItemInfo> processGift(ActivityTermEntity activityTermEntity, ActivityInfoRequest request) {
        return null;
    }

    @Override
    @FunctionInvoker(printLog = true)
    public String processSpecialOfferPrice(ActivityTermEntity activityTermEntity, ActivityInfoRequest request) {
        try {

            //参与活动主子单缓存
            CombinationItemStore combinationItemStore = CustumerCombinationItemThreadLocal.get();

            List<String> itemList = activityTermEntity.getItemList();
            String salesUnit = activityTermEntity.obtainSalesUnit();
            long sum = 0L;
            if (CollectionUtils.isNotEmpty(itemList)) {
                if (Objects.nonNull(combinationItemStore) && CollectionUtils.isNotEmpty(combinationItemStore.getCombinationItemEntityList())) {
                    List<CombinationItemGroupByMainOrderIdStore> byMainOrderIdStores = combinationItemStore.getCombinationItemEntityList()
                            .stream().filter(o -> o.getMainOrderId().equalsIgnoreCase(request.getMainOrderId())).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(byMainOrderIdStores)) {
                        List<ItemInfoEntityStore> itemInfoEntityStoreList = new ArrayList<>();
                        byMainOrderIdStores.forEach(o -> itemInfoEntityStoreList.addAll(com.alibaba.cz.base.tool.Nullable.stream(
                                o.getItemInfoEntityStoreList()).filter(x -> x.getSaleUnitCode().equals(salesUnit)).collect(Collectors.toList())));
                        sum = itemInfoEntityStoreList.stream().filter(o -> itemList.contains(o.getItemId())).mapToLong(ItemInfoEntityStore::getItemQuantity).sum();
                    }
                }
            }

//        1. 活动明细表中的货品 ID 不为空, 且特价不为空，直接获取特价信息
//        2. 原品 id在活动明细表中的货品ID列表中,且特价不为空，直接获取特价信息
            ActivityItemInfoRequest userInputItem = request.getItemList().get(0);


            if (activityTermEntity.containItemId(userInputItem.getItemId())
                    && StringUtils.isNotBlank(activityTermEntity.obtainSpecialOfferPrice()) &&
                    (BigDecimal.ZERO.compareTo(new BigDecimal(activityTermEntity.obtainSpecialOfferPrice().trim())) != 0)) {
                return activityTermEntity.obtainSpecialOfferPrice().trim();
            }

            if (sum == 0L) {
//       3. 有坎级活动列表，按坎级活动列表进行匹配
                if (CollectionUtils.isNotEmpty(activityTermEntity.getSegmentedActivityTermEntityList())) {
                    String specialOfferPrice = obtainSegmentedSpecialOfferPrice(activityTermEntity, userInputItem, userInputItem.getItemQuantity());
                    if (StringUtils.isNotBlank(specialOfferPrice)) {
                        return specialOfferPrice;
                    }
                }
            } else {
//       3. 有坎级活动列表，按坎级活动列表进行匹配
                if (CollectionUtils.isNotEmpty(activityTermEntity.getSegmentedActivityTermEntityList())) {
                    String specialOfferPrice = obtainSegmentedSpecialOfferPrice(activityTermEntity, userInputItem, sum);
                    if (StringUtils.isNotBlank(specialOfferPrice)) {
                        return specialOfferPrice;
                    }
                }
            }
            //       4. 没有坎级活动列表，直接匹配坎级活动组合表
            if (CollectionUtils.isNotEmpty(activityTermEntity.getCombinationEntityList())) {

                //计算组合匹配特价
                SegmentedActivityCombinationEntity combinationEntity = activityTermEntity.getCombinationEntityList().stream()
                        .filter(e -> e.obtainItemId().equals(userInputItem.getItemId())).findFirst().orElse(null);
                if (Objects.isNull(combinationEntity)) {
                    log.error("没有查到组合特价！！！");
                    return "";
                }
                List<SegmentedActivityCombinationEntity> combinationEntityList = activityTermEntity.getCombinationEntityList().stream()
                        .filter(entity -> StringUtils.isNotBlank(combinationEntity.obtainChangeCommonGroup())
                                && combinationEntity.obtainChangeCommonGroup().equals(entity.obtainChangeCommonGroup()))
                        .collect(Collectors.toList());

                List<SegmentedActivityCombinationEntity> allCombinationEntityList = activityTermEntity.getAllCombinationEntityList();

                String combinationSpecialPrice = calculate(request, combinationEntity, combinationEntityList, allCombinationEntityList,activityTermEntity);
                if (StringUtils.isNotBlank(combinationSpecialPrice)) {

                    activityTermEntity.setCommonGroupFlag(combinationEntity.obtainCommonGroup());

                    //设置上原品 id
                    Map<String, String> itemSpecialPriceMap = new HashMap<>();
                    combinationEntityList.forEach(entity -> itemSpecialPriceMap.put(entity.obtainItemId(), entity.obtainSegmentedActivityUnitPrice()));
                    activityTermEntity.setItemSpecialPriceMap(itemSpecialPriceMap);

                    return combinationSpecialPrice.trim();
                }
            }

        } catch (Exception e) {
            log.error("处理特价出了异常，该活动项目不被命中，活动termId=" + activityTermEntity.obtainActivityTermId(), e);
        }
        return "";
    }

    /**
     * 获取坎级特价
     *
     * @param activityTermEntity 活动term实体
     * @param userInputItem      用户输入
     * @param sum
     * @return
     */
    @Nullable
    private String obtainSegmentedSpecialOfferPrice(ActivityTermEntity activityTermEntity, ActivityItemInfoRequest userInputItem, long sum) {

//        1. activityTermEntity包含原品可以走坎级特价,
//        2. activityTermEntity不包含可以走坎级特价，但是坎级表包含货品id可以走坎级特价
//        3. 以上两种都不满足的情况下，方法直接返回
        List<SegmentedActivityTermEntity> segmentedActivityTermEntityList = new ArrayList<>();
        if (activityTermEntity.containItemId(userInputItem.getItemId())) {
            segmentedActivityTermEntityList = activityTermEntity.getSegmentedActivityTermEntityList();
        } else {
            segmentedActivityTermEntityList = activityTermEntity.getSegmentedActivityTermEntityList()
                    .stream().filter(e -> userInputItem.getItemId().equals(e.obtainItemId())).collect(Collectors.toList());
        }

        //以上两种都不满足的情况下，方法直接返回
        if (!activityTermEntity.containItemId(userInputItem.getItemId())
                && CollectionUtils.isEmpty(segmentedActivityTermEntityList)) {
            return "";
        }

        //按照原品的购买数量进行降序排列
        Collections.sort(segmentedActivityTermEntityList, (o1, o2) ->
                o1.obtainItemQuantity() <= o2.obtainItemQuantity() ? 1 : -1
        );

        for (SegmentedActivityTermEntity entity : segmentedActivityTermEntityList) {
            //过滤满足的坎级活动
            if (sum >= entity.obtainItemQuantity()) {
                //3.1 有阶梯价，命中阶梯特价
                String specialOfferPrice = entity.obtainSpecialOfferPrice();
                if (StringUtils.isNotBlank(specialOfferPrice)) {
                    return specialOfferPrice.trim();
                }
            }
        }
        return null;
    }

    /**
     * 获取价格
     *
     * @param request                  请求
     * @param combinationEntity        组合
     * @param combinationEntityList    组合实体列表
     * @param allCombinationEntityList
     * @param activityTermEntity
     * @return 价格
     */
    @ProcessInvoker(printLog = true)
    private String calculate(ActivityInfoRequest request, SegmentedActivityCombinationEntity combinationEntity, List<SegmentedActivityCombinationEntity> combinationEntityList, List<SegmentedActivityCombinationEntity> allCombinationEntityList, ActivityTermEntity activityTermEntity) {
        //获取入参
        CombinationItemStore combinationItemStore = CustumerCombinationItemThreadLocal.get();
        //获取该主单下的所有货品
        CombinationItemGroupByMainOrderIdStore mainOrderStore = combinationItemStore.getCombinationItemEntityList()
                .stream().filter(e -> e.getMainOrderId().equals(request.getMainOrderId())).findFirst().get();

        Map<String, List<ItemInfoEntityStore>> infoEntityStoreMap = mainOrderStore.obtainItemInfoEntityList();

        //同活动下的组合表买品与主单下的货品按组归类
        Map<String, List<SegmentedActivityCombinationSDO>> commonGroupMap = com.alibaba.cz.base.tool.Nullable.stream(allCombinationEntityList).map(SegmentedActivityCombinationEntity::getCombinationSDO)
                .collect(Collectors.groupingBy(SegmentedActivityCombinationSDO::getCommonGroup));

        boolean sameGroupSatisfy = true;
//        long multiple = 1L;
        HashMap<String, Long> multipleMap = new HashMap<>();
        for (Map.Entry<String, List<SegmentedActivityCombinationSDO>> combinateEntry : commonGroupMap.entrySet()) {
            List<SegmentedActivityCombinationSDO> combinationSDOS = combinateEntry.getValue();

            List<String> commonItemIdList = com.alibaba.cz.base.tool.Nullable.stream(combinationSDOS).map(SegmentedActivityCombinationSDO::getItemId).distinct().collect(Collectors.toList());

            long combinateSumQty = 0L;
            String salesUnit = activityTermEntity.obtainSalesUnit();
            for (String combinateItemId : commonItemIdList) {
                List<ItemInfoEntityStore> itemInfoEntityStore = infoEntityStoreMap.get(combinateItemId);
                if (CollectionUtils.isNotEmpty(itemInfoEntityStore)) {
                    long sum = itemInfoEntityStore.stream().filter(o->o.getSaleUnitCode().equals(salesUnit)).mapToLong(ItemInfoEntityStore::getItemQuantity).sum();
                    combinateSumQty += sum;
                }
            }
            SegmentedActivityCombinationSDO singleCombinationSDO = combinationSDOS.get(0);
            Integer itemQuantity = singleCombinationSDO.getItemQuantity();
            if (combinateSumQty % itemQuantity == 0
                    && combinateSumQty / itemQuantity > 0) {
                long multiple = combinateSumQty / itemQuantity;
                if (multipleMap.containsKey(singleCombinationSDO.getActivityId())) {
                    if (multipleMap.get(singleCombinationSDO.getActivityId()) != multiple) {
                        sameGroupSatisfy = false;
                        break;
                    }
                } else {
                    multipleMap.put(singleCombinationSDO.getActivityId(), multiple);
                }
                continue;
            }
            sameGroupSatisfy = false;
        }

        if (!sameGroupSatisfy) {
            return "";
        }
        return combinationEntity.obtainSegmentedActivityUnitPrice();
    }

    @Override
    @FunctionInvoker
    public Long calculatePreOccupyFee(ActivityTermEntity termEntity, ParticipateActivityTermRequest termRequest, boolean noNeedCalcOccupyFee) {
        ActivityItemInfo item = termRequest.getItem();
//        本次活动预占用金额=(原品常规价-特价)*原品活动使用量
        long diffPrice = item.getItemPrice() - termRequest.getSpecialOfferPrice();
        //计算预占数量
        long minPreQuantity = this.calculateOccupyQuantity(termEntity, termRequest);
        return minPreQuantity * diffPrice;
    }

    @Override
    @FunctionInvoker
    public Integer calculateOccupyQuantity(ActivityTermEntity termEntity, ParticipateActivityTermRequest termRequest) {
        ActivityItemInfo item = termRequest.getItem();
//        价差 = 商品原价 - 特价
        long diffPrice = item.getItemPrice() - termRequest.getSpecialOfferPrice();
//        本次预占费用 = 价差 * 原品数量
        long thisPreOccupyFee = diffPrice * item.getItemQuantity();
//        剩余费用 = 活动申请费用 - 活动已占用的费用
        long remainingFee = obtainRemainingFee(termEntity);
//        long remainingFee = termEntity.obtainApplyFee() - termEntity.obtainActivityOccupyFee();

//        预占数量 = Min(本次预占费用，剩余费用) / 价差
        //取最小值
        long preQuantity = Math.min(thisPreOccupyFee, remainingFee) / diffPrice;

//        最终预占数量 = Min(预占数量, 本次活动剩余数量)
        long min = Math.min(preQuantity, obtainActivityRemainingQuantity(termEntity));
        return new BigDecimal(min).intValue();
    }

    /**
     * 特价活动不过滤，全部返回true
     *
     * @param termEntity termEntity
     * @param itemId
     * @return
     */
    @Override
    public Boolean filterTermOfCreate(ActivityTermEntity termEntity, String itemId) {
        return true;
    }

    @Override
    @ProcessInvoker
    public Result<Boolean> checkParticipateActivityData(ParticipateActivityInfoRequest request, ActivityTermResponse response) {

        Long itemPrice = request.getParticipateActivityTermRequest().getItem().getItemPrice();
        if (Objects.isNull(itemPrice)) {
            log.error("参加活动失败,缺少原品价格，当前入参= {}", request);
            return Result.failure("参加活动失败,缺少原品价格");
        }

        Long participateSpecialOfferPrice = request.getParticipateActivityTermRequest().getSpecialOfferPrice();
        if (Objects.isNull(participateSpecialOfferPrice)) {
            log.error("参加活动失败,该活动是特价活动，缺少特价字段！当前活动Term入参 = {}", request.getParticipateActivityTermRequest());
            return Result.failure("参加活动失败,该活动是特价活动，缺少特价字段！");
        }

        BigDecimal itemPriceFloat=new BigDecimal(itemPrice).divide(new BigDecimal("100"),2,RoundingMode.HALF_UP);
        BigDecimal participateSpecialOfferPriceFloat=new BigDecimal(participateSpecialOfferPrice).divide(new BigDecimal("100"),2,RoundingMode.HALF_UP);
        if (itemPrice.compareTo(participateSpecialOfferPrice) < 1) {
            log.error("参加活动失败,该活动是特价活动！原品价格={}, 特价={}, 特价不应大于等于常规价格！当前活动Term入参 = {}",
                    itemPriceFloat, participateSpecialOfferPriceFloat,
                    request.getParticipateActivityTermRequest());
            return Result.failure("参加活动失败,该活动是特价活动！原品价格=" + itemPriceFloat + ", 特价=" + participateSpecialOfferPriceFloat + ", 特价不应大于等于常规价格！");
        }

        String specialOfferPrice = response.getSpecialOfferPrice();
        BigDecimal responseSpecialOfferPrice = BigDecimal.ZERO;
        if (StringUtils.isNotBlank(specialOfferPrice)) {
            responseSpecialOfferPrice = new BigDecimal(specialOfferPrice).divide(new BigDecimal("100"),2,RoundingMode.HALF_UP);
        }

        if (participateSpecialOfferPriceFloat.compareTo(responseSpecialOfferPrice) != 0) {
            log.error("参加特价活动失败，当前活动实时查询的特价和参加活动的特价不一致，实时查询的活动特价={},用户参加活动的特价={}",
                    responseSpecialOfferPrice, participateSpecialOfferPriceFloat);
            return Result.failure("参加特价活动失败，当前活动实时查询的特价和参加活动的特价不一致，实时查询的活动特价=" + responseSpecialOfferPrice + ",用户参加活动的特价=" + participateSpecialOfferPriceFloat);
        }

        return Result.success();
    }


    /**
     * 校验预占数量
     *
     * @param termEntity
     * @param termRequest
     * @param preOccupyQuantity
     * @return
     */
    @Override
    public Boolean checkPreOccupyQuantity(ActivityTermEntity termEntity, ParticipateActivityTermRequest termRequest, Integer preOccupyQuantity) {

        //查询活动抬头是否有分组管控标识
        String activityId = termEntity.obtainActivityId();
        ActivityTitleSDO activityTitleSDO = queryRepository.queryActivityTitleByActivityId(activityId);
        if (Objects.isNull(activityTitleSDO)) {
            log.error("未查询到该活动项目的活动抬头数据:{}", termEntity.obtainActivityTermId());
            return false;
        }
        String controlByGroupFlag = activityTitleSDO.getControlByGroupFlag();
        if (StringUtils.isNotBlank(controlByGroupFlag) && "X".equals(controlByGroupFlag)) {
            ActivityTitleExtSDO activityTitleExtSDO = queryRepository.queryTitleExt(activityTitleSDO.getActivityNoteId());
            if (Objects.isNull(activityTitleExtSDO)) {
                log.error("未查询到该活动项目的活动抬头扩展数据，无法进行参加该活动:{}", activityTitleSDO);
                return false;
            }

            //活动占用量校验
            Long newActivityOccupyItemQuantity = activityTitleExtSDO.getActivityOccupyQuantity() + preOccupyQuantity;
            if (activityTitleExtSDO.getApplyItemQuantity() < newActivityOccupyItemQuantity) {
                log.error("活动数量已经占用完了，该货品占用活动失败！活动申请活动量:{}, 已经占用的活动量:{},本次预占数量={},用户占用的活动量:{}",
                        activityTitleExtSDO.getApplyItemQuantity(), activityTitleExtSDO.getActivityOccupyQuantity(), preOccupyQuantity,
                        termRequest.getItem().getItemQuantity());
                return false;
            }
        } else {
            Integer newActivityOccupyItemQuantity = termEntity.obtainActivityOccupyQuantity() + preOccupyQuantity;
            if (termEntity.obtainApplyItemQuantity() < newActivityOccupyItemQuantity) {
                log.error("活动数量已经占用完了，该货品占用活动失败！活动申请活动量:{}, 已经占用的活动量:{},本次预占数量={},用户占用的活动量:{}",
                        termEntity.obtainApplyItemQuantity(), termEntity.obtainActivityOccupyQuantity(), preOccupyQuantity,
                        termRequest.getItem().getItemQuantity());
                return false;
            }
        }

        //活动占用金额校验
        ActivityItemInfo item = termRequest.getItem();
//        价差 = 商品原价 - 特价
        long diffPrice = item.getItemPrice() - termRequest.getSpecialOfferPrice();
//        本次预占费用 = 价差 * 原品数量
        long thisPreOccupyFee = diffPrice * item.getItemQuantity();
//        剩余费用 = 活动申请费用 - 活动已占用的费用
        long remainingFee = obtainRemainingFee(termEntity);

        //取最小值
        if (thisPreOccupyFee > remainingFee) {
            log.error("活动金额已经占用完了，该货品占用活动失败！,本次预占数量={},本次预占金额={},剩余金额{},",
                    termRequest.getItem().getItemQuantity(), thisPreOccupyFee, remainingFee);
            return false;
        }

        if (item.getItemQuantity() > obtainActivityRemainingQuantity(termEntity)) {
            log.error("活动数量已经占用完了，该货品占用活动失败！,本次预占数量={},剩余数量{}",
                    termRequest.getItem().getItemQuantity(), obtainActivityRemainingQuantity(termEntity));
            return false;
        }


        if (preOccupyQuantity == 0) {
            log.error("本次活动计算后预占活动数量为0，不能通过活动校验！活动申请活动量:{}, 已经占用的活动量:{},本次预占数量={},用户占用的活动量:{}",
                    termEntity.obtainApplyItemQuantity(), termEntity.obtainActivityOccupyQuantity(), preOccupyQuantity,
                    termRequest.getItem().getItemQuantity());
            return false;
        }

        return true;
    }

    /**
     * 校验预占金额
     *
     * @param termEntity       活动项目实体
     * @param thisPreOccupyFee 本次预占费用
     * @return true: 校验通过，false:校验不通过
     */
    @Override
    public Boolean checkPreOccupyFee(ActivityTermEntity termEntity, Long thisPreOccupyFee) {
//        if (thisPreOccupyFee == 0L) {
//            log.error("活动占用数量失败！预占金额为0的情况，活动申请费用:{},活动已占用费用:{},本次申请费用:{}，活动termId={}",
//                    termEntity.obtainApplyFee(), termEntity.obtainActivityOccupyFee(), thisPreOccupyFee, termEntity.obtainActivityTermId());
//            return false;
//        }

        //查询活动抬头是否有分组管控标识
        String activityId = termEntity.obtainActivityId();
        ActivityTitleSDO activityTitleSDO = queryRepository.queryActivityTitleByActivityId(activityId);
        if (Objects.isNull(activityTitleSDO)) {
            log.error("未查询到该活动项目的活动抬头数据:{}", termEntity.obtainActivityTermId());
            return false;
        }
        String controlByGroupFlag = activityTitleSDO.getControlByGroupFlag();
        if (StringUtils.isNotBlank(controlByGroupFlag) && "X".equals(controlByGroupFlag)) {
            ActivityTitleExtSDO activityTitleExtSDO = queryRepository.queryTitleExt(activityTitleSDO.getActivityNoteId());
            if (Objects.isNull(activityTitleExtSDO)) {
                log.error("未查询到该活动项目的活动抬头扩展数据，无法进行参加该活动:{}", activityTitleSDO);
                return false;
            }

            //活动占用费用校验
            Long activityOccupyFee = activityTitleExtSDO.getActivityOccupyFee() + thisPreOccupyFee;
            if (activityTitleExtSDO.getApplyFee() < activityOccupyFee) {
                log.error("活动占用费用失败！活动申请费用:{},活动已占用费用:{},本次申请费用:{}",
                        activityTitleExtSDO.getApplyFee(), activityTitleExtSDO.getActivityOccupyFee(), thisPreOccupyFee);
                return false;
            }
        } else {
            //正常是不会被校验的，这里是做了兜底措施
            long activityOccupyFee = termEntity.obtainActivityOccupyFee() + thisPreOccupyFee;
            if (termEntity.obtainApplyFee() < activityOccupyFee) {
                log.error("活动占用费用失败！活动申请费用:{},活动已占用费用:{},本次申请费用:{}",
                        termEntity.obtainApplyFee(), termEntity.obtainActivityOccupyFee(), thisPreOccupyFee);
                return false;
            }
        }

        return true;
    }

    //获取剩余费用
    @ProcessInvoker
    public Long obtainRemainingFee(ActivityTermEntity termEntity) {
        //查询活动抬头是否有分组管控标识
        String activityId = termEntity.obtainActivityId();
        ActivityTitleSDO activityTitleSDO = queryRepository.queryActivityTitleByActivityId(activityId);
        if (Objects.isNull(activityTitleSDO)) {
            log.error("未查询到该活动项目的活动抬头数据:{}", termEntity.obtainActivityTermId());
            throw new ProcessException("OTS-08-002-01-16-012");
        }
        String controlByGroupFlag = activityTitleSDO.getControlByGroupFlag();
        if (StringUtils.isNotBlank(controlByGroupFlag) && "X".equals(controlByGroupFlag)) {
            ActivityTitleExtSDO activityTitleExtSDO = queryRepository.queryTitleExt(activityTitleSDO.getActivityNoteId());
            if (Objects.isNull(activityTitleExtSDO)) {
                log.error("未查询到该活动项目的活动抬头扩展数据，无法进行参加该活动:{}", activityTitleSDO);
                throw new ProcessException("OTS-08-002-01-16-013");
            }
            return activityTitleExtSDO.getApplyFee() - activityTitleExtSDO.getActivityOccupyFee();
        } else {
            return termEntity.obtainApplyFee() - termEntity.obtainActivityOccupyFee();
        }
    }

    /**
     * 获取活动剩余数量
     *
     * @param termEntity
     * @return
     */
    @ProcessInvoker
    public Integer obtainActivityRemainingQuantity(ActivityTermEntity termEntity) {
        //查询活动抬头是否有分组管控标识
        String activityId = termEntity.obtainActivityId();
        ActivityTitleSDO activityTitleSDO = queryRepository.queryActivityTitleByActivityId(activityId);
        if (Objects.isNull(activityTitleSDO)) {
            log.error("未查询到该活动项目的活动抬头数据:{}", termEntity.obtainActivityTermId());
            throw new ProcessException("OTS-08-002-01-16-012");
        }
        String controlByGroupFlag = activityTitleSDO.getControlByGroupFlag();
        if (StringUtils.isNotBlank(controlByGroupFlag) && "X".equals(controlByGroupFlag)) {
            ActivityTitleExtSDO activityTitleExtSDO = queryRepository.queryTitleExt(activityTitleSDO.getActivityNoteId());
            if (Objects.isNull(activityTitleExtSDO)) {
                log.error("未查询到该活动项目的活动抬头扩展数据，无法进行参加该活动:{}", activityTitleSDO);
                throw new ProcessException("OTS-08-002-01-16-013");
            }
            Long remainingQuantity = activityTitleExtSDO.getApplyItemQuantity() - activityTitleExtSDO.getActivityOccupyQuantity();
            return remainingQuantity.intValue();
        } else {
            return termEntity.obtainActivityRemainingQuantity();
        }
    }
}
